package services

import (
	"fmt"
	"go-tool/components"
	"go-tool/db/orm_iray_proxy"
	"gopkg.in/olivere/elastic.v5"
	"reflect"
	"strings"
	"time"
)

type JobLog struct {
	Timestamp          time.Time `json:"@timestamp"`
	Ts                 time.Time `json:"ts"`
	LogTopic           string    `json:"log_topic"`
	Msg                string    `json:"msg"`
	JobID              string    `json:"jobId"`
	Stat               string    `json:"stat"`
	IrayIP             string    `json:"irayIp"`
	ConstructIP        string    `json:"constructIp"`
	JobStartTime       string    `json:"jobStartTime"`       //任务开始时间
	JobEndTime         string    `json:"jobEndTime"`         //任务结束时间
	ConstructStartTime string    `json:"constructStartTime"` //开始构建时间
	RenderType         int       `json:"renderType"`         //渲染类型
	Retries            int       `json:"retries"`            //重试次数
	TotalCost          int64     `json:"totalCost"`          //总耗时
	ConstructWaitCost  int64     `json:"constructWaitCost"`  //构建等待时长
}

func (e *JobLog) DbToLog(info orm_iray_proxy.JobInfo) *JobLog {
	e = &JobLog{
		Timestamp:          info.UploadEndTime.Time.UTC(),
		Ts:                 info.UploadEndTime.Time.Local(),
		LogTopic:           "cloud-rendering-stat",
		JobID:              info.JobId,
		IrayIP:             info.Ip.String,
		Stat:               "jobCostStat",
		Msg:                "jobCostStat",
		JobStartTime:       info.JobStartTime.Time.Local().Format("2006-01-02 15:04:05"),
		JobEndTime:         info.UploadEndTime.Time.Local().Format("2006-01-02 15:04:05"),
		ConstructStartTime: info.StrInitStartTime.Time.Local().Format("2006-01-02 15:04:05"),
		RenderType:         info.RenderType,
		Retries:            info.Retries,
		TotalCost:          info.UploadEndTime.Time.Local().Unix() - info.JobStartTime.Time.Unix(),
		ConstructWaitCost:  info.StrInitStartTime.Time.Local().Unix() - info.JobStartTime.Time.Unix(),
	}
	if index := strings.Index(info.ConstructIp.String, ":"); info.ConstructIp.Valid && index > 0 {
		e.ConstructIP = info.ConstructIp.String[0:index]
	}
	return e
}

func (e *JobLog) InsertEs() (err error) {
	components.EsClient.Index = "cloud-rendering-stat-" + e.Timestamp.Local().Format("2006.01")
	components.EsClient.Type = "doc"
	put, err := components.EsClient.Push(e)
	if err != nil {
		panic(err)
		fmt.Printf("Indexed tweet %s to index s%s, type %s\n", put.Id, put.Index, put.Type)
	}
	return
}

func (e *JobLog) Each(startTime string, endTime string) (count int) {
	DbJob := orm_iray_proxy.JobInfo{}
	minId, maxId := DbJob.QueryOtherResultMinIdAndMaxIdByTime(startTime, endTime)
	limit := 5000
	obj := JobLog{}
	for {
		fmt.Printf("start joblog, id: %v - %v \n", minId, maxId)
		rows, err := DbJob.QueryByConstruct(minId, maxId, int64(limit))
		if err != nil {
			fmt.Println("err: ", err)
			return
		}
		if len(rows) == 0 {
			fmt.Println("rows len : ", len(rows))
			return
		}
		for i := 0; i < len(rows); i++ {
			rows[i].SetStrInitStartTimeByJobId()
			err = obj.DbToLog(rows[i]).InsertEs()
			if err != nil {
				fmt.Println("err: ", err)
				return
			}
			count++
			minId = int64(rows[i].Id)
			if count%100 == 0 {
				fmt.Println("count: ", count)
			}
		}
	}
	return
}

func (e *JobLog) EachEs() (count int) {
	components.EsClient.Index = "job"
	components.EsClient.Type = "log"
	//675849
	max := 675849
	offset := 0
	limit := 1
	for {
		q := elastic.NewQueryStringQuery("stat:jobCostStat")
		searchResult, err := components.EsClient.Search(q, offset, limit)
		if err != nil || len(searchResult.Hits.Hits) == 0 {
			fmt.Println(err)
			return
		}
		var obj JobLog
		for _, item := range searchResult.Each(reflect.TypeOf(obj)) {
			t := item.(JobLog)
			t.Ts = t.Timestamp.Local()
			t.LogTopic = "cloud-rendering-stat"
			t.Msg = t.Stat
			err = t.InsertPrdEs()
			if err != nil {
				fmt.Println(err)
			}
			count++
			if count%1000 == 0 {
				fmt.Println("count: ", count)
			}
		}
		offset = offset + limit
		if offset > max {
			return
		}
	}
	return
}

func (e *JobLog) InsertPrdEs() (err error) {
	components.EsClientPrd.Index = "cloud-rendering-stat-" + e.Timestamp.Local().Format("2006.01")
	components.EsClientPrd.Type = "doc"
	put, err := components.EsClientPrd.Push(e)
	if err != nil {
		fmt.Printf("Indexed tweet %s to index s%s, type %s\n", put.Id, put.Index, put.Type)
		panic(err)
	}
	return
}
